#include <iostream>
#include <vector>

using namespace std;

inline double isLeft( double x0,double y0,double x1, double y1,double x2,double y2) {
  return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
}


#define FOR(a,start,end) for(int a = int(start); a < int(end); a++)

#define PB push_back

vector<double> Hx;
vector<double> Hy;

void convexHull( vector<double> Px, vector<double> Py)
{
    Hx.clear();
    Hy.clear();
    
    FOR(i,0,Px.size())
	FOR(j,0,i)
		if(Px[i] < Px[j] || (Px[i] == Px[j] && Py[i] < Py[j]))
		{
			swap(Px[i],Px[j]);
			swap(Py[i],Py[j]);
		}

    int minmin = 0;
    int minmax;
    double xmin = Px[0];
    FOR(i,1,Px.size())
        if (Px[i] != xmin)
        {
        	minmax = i-1;
        	break;
        }

    if(minmax == Px.size()-1) 
    { 
		Hx.PB(Px[minmin]);
		Hy.PB(Py[minmin]);
		
        if(Py[minmax] != Py[minmin])
		{
		    Hx.PB(Px[minmax]);
	    	Hy.PB(Py[minmax]);
		}
		
		Hx.PB(Px[minmin]);
		Hy.PB(Py[minmin]);
        return;
    }

    int maxmin;
    int maxmax = Px.size()-1;
    double xmax = Px[Px.size()-1];
    for(int i = Px.size()-2; i >= 0; i--)
        if(Px[i] != xmax)
        {
        	maxmin = i+1;
        	break;
        }
        
    Hx.PB(Px[minmin]);
    Hy.PB(Py[minmin]);

    int i = minmax;
    while(++i <= maxmin)
    {
        if(isLeft(Px[minmin],Py[minmin],Px[maxmin],Py[maxmin],Px[i],Py[i]) >= 0 && i < maxmin) continue;  
	
        while(Hx.size() > 1)  
        {
            if(isLeft(Hx[Hx.size()-2], Hy[Hy.size()-2], Hx[Hx.size()-1], Hy[Hy.size()-1], Px[i], Py[i]) > 0) break;
            else
	    	{
		  		Hx.pop_back(); Hy.pop_back();
 	    	}
        }
        Hx.PB(Px[i]);
		Hy.PB(Py[i]);
    }

    if(maxmax != maxmin)
    { 
        Hx.PB(Px[maxmax]);
		Hy.PB(Py[maxmax]);
    }

    int bot = Hx.size()-1;        
    i = maxmin;
    while(--i >= minmax)
    {
        if(isLeft(Px[maxmax], Py[maxmax], Px[minmax], Py[minmax], Px[i], Py[i]) >= 0 && i > minmax) continue;      

        while(Hx.size()-1 > bot)   
        {
            if(isLeft( Hx[Hx.size()-2],Hy[Hy.size()-2],Hx[Hx.size()-1],Hy[Hy.size()-1],Px[i],Py[i]) > 0)
                break;       
            else
		    {
				Hx.pop_back(); Hy.pop_back();
		    }
        }
        Hx.PB(Px[i]);
		Hy.PB(Py[i]);
    }
    if(minmax != minmin)
    {	
        Hx.PB(Px[minmin]);
		Hy.PB(Py[minmin]);
    }
    return;
}


int main()
{
       int n;
       while(cin >> n && n != 0)
       {
               vector<double> xx;
               vector<double> yy;
               for(int i = 0; i < n; i++)
               {
                       double tmp1, tmp2;
                       cin >> tmp1 >> tmp2;
                       xx.push_back(tmp1);
                       yy.push_back(tmp2);
               }
               convexHull(xx,yy);
               
               Hx.pop_back();
               Hy.pop_back();
               
               cout << Hx.size() << endl; //size of convex hull
               for(int i = 0; i < Hx.size(); i++)
                       cout << Hx[i] << " " << Hy[i] << endl;  //points in hull
               cout << endl;
       }
       return 0;
}
